home *** CD-ROM | disk | FTP | other *** search
- /*
- * Listing 3
- *
- * TESTRDC.C - Ross Data Compression (RDC)
- * test driver program
- *
- * Written by Ed Ross, 1/92
- *
- * This program will compress or decompress a file
- * using RDC data compression.
- *
- */
-
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <string.h>
-
- #define HASH_LEN 4096 /* # hash table entries */
- #define BUFF_LEN 16384 /* size of disk io buffer */
-
- typedef unsigned char uchar; /* 8 bits, unsigned */
- typedef unsigned int uint; /* 16 bits, unsigned */
-
- uchar *hash_tbl[HASH_LEN]; /* hash table */
-
- uchar inbuff[BUFF_LEN]; /* io buffers */
- uchar outbuff[BUFF_LEN];
-
- FILE *infile, *outfile; /* FILE access */
-
- char usage[] =
- "\nUsage: TESTRDC <c | d> <infile> <outfile>\n"
- " c = compress infile to outfile\n"
- " d = decompress infile to outfile\n";
-
- /* compression function prototypes */
-
- int rdc_compress(uchar *inbuff, uint inbuff_len,
- uchar *outbuff,
- uchar *hash_tbl[], uint hash_len);
-
- int rdc_decompress(uchar *inbuff, uint inbuff_len,
- uchar *outbuff);
-
- /*--- post error message and exit ---*/
-
- void err_exit(char *fmt, ...)
- {
- va_list v;
-
- va_start(v, fmt);
- vfprintf(stderr, fmt, v);
- va_end(v);
-
- exit(1);
- }
-
- /*--- compress infile to outfile ---*/
-
- void do_compress(void)
- {
- int bytes_read;
- int compress_len;
-
- /* read infile BUFF_LEN bytes at a time */
-
- while ((bytes_read =
- fread(inbuff, 1, BUFF_LEN, infile)) > 0)
- {
- /* compress this load of bytes */
-
- compress_len = rdc_compress(inbuff, bytes_read,
- outbuff, hash_tbl, HASH_LEN);
-
- /* write length of compressed buffer */
-
- if (fwrite(&compress_len, sizeof(int),
- 1, outfile) != 1)
- err_exit("Error writing block length.\n");
-
- /* check for negative length indicating the
- buffer could not be compressed */
-
- if (compress_len < 0)
- compress_len = 0 - compress_len;
-
- /* write the buffer */
-
- if (fwrite(outbuff, compress_len, 1, outfile) != 1)
- err_exit("Error writing compressed data.\n");
-
- /* we're done if less than full buffer was read */
-
- if (bytes_read != BUFF_LEN)
- break;
- }
-
- /* add trailer to indicate end of file */
-
- compress_len = 0;
-
- if (fwrite(&compress_len, sizeof(int),
- 1, outfile) != 1)
- err_exit("Error writing trailer.\n");
- }
-
- /*--- decompress infile to outfile ---*/
-
- void do_decompress(void)
- {
- int block_len;
- int decomp_len;
-
- /* read infile BUFF_LEN bytes at a time */
-
- for (;;)
- {
- if (fread(&block_len, sizeof(int), 1, infile) != 1)
- err_exit("Can't read block length.\n");
-
- /* check for end-of-file flag */
-
- if (block_len == 0)
- return;
-
- if (block_len < 0) /* copy uncompressed chars */
- {
- decomp_len = 0 - block_len;
- if (fread(outbuff, decomp_len, 1, infile) != 1)
- err_exit("Can't read uncompressed block.\n");
- }
- else /* decompress this buffer */
- {
- if (fread(inbuff, block_len, 1, infile) != 1)
- err_exit("Can't read compressed block.\n");
-
- decomp_len = rdc_decompress(inbuff, block_len,
- outbuff);
- }
-
- /* and write this buffer outfile */
-
- if (fwrite(outbuff, decomp_len, 1, outfile) != 1)
- err_exit("Error writing uncompressed data.\n");
- }
- }
-
- /*--- main ---*/
-
- void main(int argc, char *argv[])
- {
- /* check command line */
-
- if (argc != 4)
- err_exit(usage);
-
- /* open the files */
-
- if ((infile = fopen(argv[2], "rb")) == NULL)
- err_exit("Can't open %s for input.\n", argv[2]);
-
- if ((outfile = fopen(argv[3], "wb")) == NULL)
- err_exit("Can't open %s for output.\n", argv[3]);
-
- /* dispatch to requested function */
-
- switch (argv[1][0])
- {
- case 'c':
- case 'C':
- do_compress();
- break;
-
- case 'd':
- case 'D':
- do_decompress();
- break;
-
- default:
- err_exit(usage);
- }
-
- /* and close the files */
-
- if (fclose(infile))
- err_exit("Error closing input file.\n");
-
- if (fclose(outfile))
- err_exit("Error closing output file.\n");
- }
-